home *** CD-ROM | disk | FTP | other *** search
/ FM Towns: Free Software Collection 7 / FM Towns Free Software Collection 7.iso / ms_dos / dmove86 / dmmenu.c < prev    next >
Text File  |  1993-11-30  |  7KB  |  399 lines

  1. /*
  2.  
  3. dmove86 version 1.20a
  4. Copyright (c) 1993 Delmonta
  5.  
  6. dmmenu.c -- メニューモジュール
  7.  
  8. */
  9.  
  10. #include<stdio.h>
  11. #include<dos.h>
  12. #include"escseq.h"
  13. #include"dmove86.h"
  14.  
  15. #define    RIGHT    '\x1c'
  16. #define    LEFT    '\x1d'
  17. #define    UP    '\x1e'
  18. #define    DOWN    '\x1f'
  19.  
  20. unsigned int    Pagenum,Lastnum;    /* ページ数・最終ページのエントリ数 */
  21. unsigned int    Page,Pos;        /* 現在のページ番号とカーソル位置  */
  22. unsigned int    Selected;        /* 選択され反転表示されている番号  */
  23. struct DIRENTRY    far **Dirtbl;
  24. int        Changedflag;        /* 変更があったかどうかのフラグ    */
  25.  
  26. static    void    putfilename(p,f)    /* 画面にファイル名を表示          */
  27. int        p,f;            /* f=-1のときは、"::::::::.:::"を表示 */
  28. {
  29.     LOCATE( (p%6)*13 , p/6+2);
  30.  
  31.     if    (Page*96+p == Selected)
  32.         printf("\033[7m");
  33.  
  34.     if    ( f==-1)
  35.         printf("             ");
  36.     else if    (Dirtbl[Page*96+p]->filename[0]=='\xe5')
  37.         printf(" ::::::::.:::");
  38.     else
  39.     {
  40.         int    i;
  41.  
  42.         if    (Dirtbl[Page*96+p]->attr & _A_SUBDIR)
  43.             printf("\033[32m");    /* ディレクトリは緑 */
  44.         else if    (Dirtbl[Page*96+p]->attr & _A_VOLID)
  45.             printf("\033[35m");    /* ボリュームIDは紫 */
  46.         else if    (Dirtbl[Page*96+p]->attr & _A_SYSTEM)
  47.             printf("\033[31m");    /* システムファイルは赤 */
  48.         else
  49.             printf("\033[37m");    /* そのほかは白 */
  50.  
  51.         putchar(' ');
  52.         for    (i=0 ; i<8 ; i++)
  53.             putchar(Dirtbl[Page*96+p]->filename[i]);
  54.  
  55.         putchar('.');
  56.  
  57.         for    (i=0 ; i<3 ; i++)
  58.             putchar(Dirtbl[Page*96+p]->extname[i]);
  59.  
  60.     }
  61.  
  62.     printf(" \033[0;37m");
  63. }
  64.  
  65. static    void    putpage()    /* ページ表示 */
  66. {
  67.     int        i;
  68.  
  69.     for    (i=0 ; i<96 ; i++)
  70.     {
  71.         if    (Page==Pagenum-1 && i==Lastnum)
  72.             for    ( ; i<96 ; i++)
  73.                 putfilename(i,-1);
  74.         else
  75.             putfilename(i,0);
  76.     }
  77. }
  78.  
  79. void    putcursor(void)
  80. {
  81. static    int    oldx = -1,
  82.         oldy = -1;
  83.  
  84.     if    (oldx != -1)
  85.     {
  86.         LOCATE(oldx*13   ,oldy+2);
  87.         putchar(' ');
  88.         LOCATE(oldx*13+13,oldy+2);
  89.         putchar(' ');
  90.     }
  91.  
  92.     oldx = Pos%6;
  93.     oldy = Pos/6;
  94.  
  95.     LOCATE(oldx*13   ,oldy+2);
  96.     putchar('<');
  97.     LOCATE(oldx*13+13,oldy+2);
  98.     putchar('>');
  99.  
  100. }
  101.  
  102. static    char    movecursor(flag)    /* カーソル移動・キー入力           */
  103. int        flag;            /* カーソル・スペース・ESC以外を受け付けるか */
  104. {
  105.     int    c;
  106.  
  107.     selectflag(!flag);
  108.  
  109. LOOP:;
  110.     putcursor();
  111.  
  112.     while(kbhit() == 0)
  113.         ;
  114.  
  115.     c = getch();
  116.  
  117.     if    (c == '\3')
  118.         endscreen();
  119.  
  120.     if    (c == '\x1a')
  121.         endscreen();
  122.  
  123.     switch    (c)
  124.     {
  125.     case '6':
  126.     case 'D'-0x40:    /* ^D */
  127.     case RIGHT:
  128.         Pos++;
  129.         if    (Pos==96 || (Page==Pagenum-1 && Pos==Lastnum) )
  130.             Pos=0;
  131.         break;
  132.  
  133.     case '4':
  134.     case 'S'-0x40:    /* ^S */
  135.     case LEFT:
  136.         if    (Pos==0)
  137.         {
  138.             if    (Page==Pagenum-1)
  139.                 Pos = Lastnum-1;
  140.             else
  141.                 Pos = 95;
  142.         }
  143.         else
  144.             Pos--;
  145.         break;
  146.  
  147.     case '8':
  148.     case 'E'-0x40:    /* ^E */
  149.     case UP:
  150.         if    (Pos>=6)
  151.             Pos = Pos-6;
  152.         break;
  153.  
  154.     case '2':
  155.     case 'X'-0x40:    /* ^X */
  156.     case DOWN:
  157.         if    (Pos>=96-6 || (Page==Pagenum-1 && Pos+6>=Lastnum) )
  158.             ;    /* Pos>=Lastnum-6では、Lastnum-6<0となって   */
  159.         else        /* Posがunsignedの為正確に判断できない場合有 */
  160.             Pos = Pos+6;
  161.         break;
  162.  
  163.     case '-':
  164.         if    (Page>=1)
  165.         {
  166.             Page--;
  167.             putpage();
  168.         }
  169.         break;
  170.  
  171.     case '+':
  172.         if    (Page<Pagenum-1)
  173.         {
  174.             Page++;
  175.  
  176.             if    (Page==Pagenum-1 && Pos>=Lastnum)
  177.                 Pos = Lastnum-1;
  178.  
  179.             putpage();
  180.         }
  181.         break;
  182.  
  183.     case ' ':
  184.         if    (Dirtbl[Page*96+Pos]->filename[0]!='.')
  185.             return c;
  186.         else
  187.             dm_errmes("\".\"や\"..\"に対しては操作できません.");
  188.         break;
  189.  
  190.     case '\033':
  191.         return c;
  192.  
  193.     default:
  194.         if    (flag)
  195.             return c;
  196.  
  197.         break;
  198.     }
  199.  
  200.     goto LOOP;
  201. }
  202.  
  203. int    chkflag(void)
  204. {
  205.     if    (Changedflag==0)
  206.         return 1;
  207.  
  208.     printf( "\033[19;1H\033[31m"
  209.         "内容の変更があります. よろしいですか(y/n)?"
  210.         "\033[37m");
  211.  
  212. chkflag_loop:;
  213.  
  214.     while    (!kbhit())
  215.         ;
  216.  
  217.     switch(getch())
  218.     {
  219.     case 'Y':
  220.     case 'y':
  221.         printf("\033[19;1H\033[2K");
  222.         return 1;
  223.     case 'N':
  224.     case 'n':
  225.         printf("\033[19;1H\033[2K");
  226.         return 0;
  227.     default:
  228.         break;
  229.     }
  230.     goto chkflag_loop;
  231. }
  232.  
  233. unsigned int    dmmenu(dirtbl,dirnum,cursorpos,issubdir)
  234. struct DIRENTRY    far **dirtbl;
  235. unsigned int    dirnum,cursorpos;
  236. int        issubdir;
  237. {
  238.  
  239.     struct DIRENTRY    far *d;
  240.     unsigned int    i;
  241.  
  242.     Dirtbl = dirtbl;    /* 下請関数でも値を使えるようにするため */
  243.  
  244.     Selected = -1;
  245.     Changedflag = 0;
  246.  
  247.     Pagenum = dirnum/96;
  248.     Lastnum = dirnum%96;
  249.     if    (Lastnum)    Pagenum++;
  250.     else            Lastnum = 96;
  251.  
  252.     if    (cursorpos>dirnum)    /* cursorposが不正な場合 */
  253.         cursorpos = 0;
  254.  
  255.     Page = cursorpos/96;
  256.     Pos  = cursorpos%96;
  257.  
  258.     putpage();
  259.  
  260. dmmenu_loop:;
  261.  
  262.     switch(movecursor(1))
  263.     {
  264.     case 'I':
  265.     case 'i':
  266.         if    ((d=dirtbl[dirnum-1])->filename[0]=='\xe5')
  267.         {
  268.             for    (i=dirnum-1 ; i>Page*96+Pos ; i--)
  269.                 dirtbl[i] = dirtbl[i-1];
  270.  
  271.             dirtbl[Page*96+Pos] = d;
  272.  
  273.             Changedflag = 1;
  274.             putpage();
  275.         }
  276.         else
  277.             putchar('\7');
  278.  
  279.         break;
  280.  
  281.     case 'D':
  282.     case 'd':
  283.         if    ((d=dirtbl[Page*96+Pos])->filename[0]=='\xe5')
  284.         {
  285.             for    (i=Page*96+Pos ; i<dirnum-1 ; i++)
  286.                 dirtbl[i] = dirtbl[i+1];
  287.  
  288.             dirtbl[dirnum-1] = d;
  289.             Changedflag = 1;
  290.             putpage();
  291.         }
  292.         else
  293.             putchar('\7');
  294.  
  295.         break;
  296.  
  297.     case ' ':
  298.         Selected = Page*96+Pos;
  299.  
  300.         putfilename(Pos,0);            /* 反転表示 */
  301.         if    (movecursor(0)==' ' && Selected!=Page*96+Pos)
  302.         {
  303.             d = dirtbl[Selected];
  304.             dirtbl[Selected] = dirtbl[Page*96+Pos];
  305.             dirtbl[Page*96+Pos] = d;
  306.             Changedflag = 1;
  307.  
  308.         }
  309.  
  310.         if    (Selected/96 == Page)        /* 反転を解除 */
  311.         {
  312.             i = Selected%96;
  313.             Selected = -1;
  314.             putfilename(i,0);
  315.         }
  316.         else
  317.             Selected = -1;
  318.  
  319.         putfilename(Pos,0);
  320.  
  321.         break;
  322.  
  323.     case '\033':
  324.  
  325.         break;
  326.  
  327.     case 'S':
  328.     case 's':
  329.         Selected = Page*96+Pos;
  330.  
  331.         putfilename(Pos,0);            /* 反転表示 */
  332.  
  333.         printf( "\033[19;1f\033[37m"
  334.             "ソート:終点を指定してください\n");
  335.  
  336.         if    (movecursor(0)==' ' && Selected!=Page*96+Pos)
  337.         {
  338.             unsigned int    s = Selected,
  339.                     e = Page*96+Pos;
  340.  
  341.             if    (s>e)
  342.             {
  343.                 register unsigned int    a = e;
  344.                 e = s;
  345.                 s = a;
  346.             }
  347.  
  348.             dmsort(dirtbl,s,e);
  349.             Changedflag = 1;
  350.         }
  351.  
  352.         Selected = -1;
  353.  
  354.         putpage();
  355.  
  356.         break;
  357.  
  358.     case 'R':
  359.     case 'r':
  360.         dm_errmes("この機能は現時点ではサポートされていません.");
  361.         break;
  362.  
  363.     case 'C':
  364.     case 'c':
  365.     case '\r':    /* getch()が返す改行キーのコードは'\n'ではなく'\r' */
  366.         if    ((dirtbl[Page*96+Pos]->attr & _A_SUBDIR)
  367.             && dirtbl[Page*96+Pos]->filename[0]!='.')
  368.             return (Page*96+Pos)*4 + CHGDIR;
  369.         break;
  370.  
  371.     case 'O':
  372.     case 'o':
  373.         return (Page*96+Pos)*4 + ORIGIN;
  374.  
  375.     case 'U':
  376.     case 'u':
  377.     case '\x08':
  378.         if    (!issubdir)
  379.             dm_errmes("ルートの親ディレクトリはありません.");
  380.         else if    (chkflag())
  381.             return (Page*96+Pos)*4 + UPDIR;
  382.         break;
  383.  
  384.     case 'W':
  385.     case 'w':
  386.         return (Page*96+Pos)*4 + WRTDIR;
  387.  
  388.     case 'Q':
  389.     case 'q':
  390.         if    (chkflag())
  391.             endscreen();
  392.  
  393.     default:
  394.         putchar('\7');
  395.     }
  396.     goto dmmenu_loop;
  397. }
  398.  
  399.